package EA.testproblems;
import EA.*;

/**
/**

<table border="0" cellpadding="2" cellspacing="0">
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Problem description</b></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top" width="200"><b>Name:</b></td>
  <td valign="top">SchafferTilted F6</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Nickname:</b></td>
  <td valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Intended usage:</b></td>
  <td valign="top">Harder test for global optimization. The problems contains
  "minimum rings" around the global minima with almost the same fitness as
  the global minima.
</td>
</tr>

<tr>
  <td colspan="2" valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Problem details</b></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Function:</b></td>
  <td valign="top">0.5 + (sin<sup>2</sup>(sqrt(x<sup>2</sup> + y<sup>2</sup>)) - 0.5)/((1 + 0.001(x<sup>2</sup> + y<sup>2</sup>))<sup>2</sup>)+ 0.0005*x + 0.0002*y
</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Plots:</b></td>
  <td valign="top"><img src="../../images/testproblems/schaffertiltedf6.gif">&nbsp;&nbsp;
<img src="../../images/testproblems/schaffertiltedf6_contour.gif"></td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Ranges:</b></td>
  <td valign="top">x = [-5:5]&nbsp;&nbsp;y = [-5:5] </td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Type:</b></td>
  <td valign="top">Minimization</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>No. of maximas:</b></td>
  <td valign="top">?</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>No. of minimas:</b></td>
  <td valign="top">More than 10</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Optima radius:</b></td>
  <td valign="top">0.15
</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Optima descriptions:</b></td>
  <td valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#e0e0e0">
  <td valign="top"><b>Known optimas:</b></td>
  <td valign="top"><br><font size=1>Capital letters 
means that the precise optima is known, lowercase letters is the best known 
so far.</font></td>
</tr>
<tr>
  <td colspan="2" valign="top">&nbsp;</td>
</tr>
<tr bgcolor="#a0a0a0">
  <td colspan="2" valign="top"><b>Plotting details</b></td>
</tr>

<tr bgcolor="#e0e0e0">
  <td valign="top"><b>GNUPlot code:</b></td>
  <td valign="top">
  set hidden3d<br>
  set isosamples 40<br>
  set view 70,15<br>
  splot [-5:5] [-5:5] -20*exp(-0.2*sqrt(0.5*(x*x+y*y))) - exp(0.5*(cos(2*pi*x)+cos(2*pi*y))) + 20 + exp(1)
</td>

</tr>

</table>

*/
public class AckleyF1_3D extends NumericalProblem 
{

  // Easier way to build max and min
  private double[][] lmax = new double[0][2];
  /*
{[.5309764462, -2.741595535], [1.651848146, 1.651848146], [-.6730965200, .6730965200], [2.632172109, 2.632172109], [2.7415\
95535, .5309764462], [-1.591838713, 2.686140883], [2.632172109, -2.632172109], [-.5309764462, 2.741595535], [-2.686140883,
1.591838713], [-.5309764462, -2.741595535], [.6730965200, -.6730965200], [-1.651848146, 1.651848146], [-1.773445148, -.5495\
858144], [-1.651848146, -1.651848146], [-.5495858144, 1.773445148], [-2.741595535, .5309764462], [-2.632172109, -2.63217210\
9], [2.741595535, -.5309764462], [.5309764462, 2.741595535], [-2.741595535, -.5309764462], [-2.632172109, 2.632172109], [-1\
.773445148, .5495858144]}
   */

  private double[][] lmin = {
			     {-.9521665458,0,0}, 
			     {0,-.9521665458,0}, 
			     {0,0, -.9521665458}, 

			     {.9521665458,0,0},
			     {0,.9521665458,0}, 
			     {0,0, .9521665458}, 
			     
			     {0,0,0}};

    public AckleyF1_3D()
    {
      super();

      double[] optimas;
      int i,j;

      name = "Ackley F1 - 3D";
      objectivefunction = new NumericalFitness(){
	      public double Fitness_calcFitness_inner(double[] realpos)
	      {
		double sqrsum = 0;
		double cossum = 0;
		int idx;

		for (idx=0;idx<realpos.length;idx++) {
		  sqrsum += realpos[idx]*realpos[idx];
		  cossum += Math.cos(2*Math.PI*realpos[idx]);
		};
		
		return 20 + Math.E - 20*Math.exp(-0.2*Math.sqrt(sqrsum/realpos.length)) - Math.exp(cossum/realpos.length);
	      };
	  };

      dimensions = 3;
      ismaximization = false;
      optimumradius = 0.2;

      intervals = new Interval[dimensions];
      for (i=0;i<dimensions;i++) {
	intervals[i] = new Interval(-30,30);
      }
      
      // Set up known maximas
      knownmaxima = new NumericalOptimum[lmax.length];

      for (i=0;i<lmax.length;i++) {
	optimas = new double[dimensions];
        for (j=0;j<dimensions;j++) {
	  optimas[j] = lmax[i][j];
	}
	knownmaxima[i] = new NumericalOptimum(optimas, objectivefunction.calcFitness(optimas), true, false, i);
      }

      // Set up known minimas
      knownminima = new NumericalOptimum[lmin.length];

      for (i=0;i<lmin.length;i++) {
	optimas = new double[dimensions];
        for (j=0;j<dimensions;j++) {
	  optimas[j] = lmin[i][j];
	}
	knownminima[i] = new NumericalOptimum(optimas, objectivefunction.calcFitness(optimas), false, false, i);
      }
    }
}
